﻿using System;

namespace CSharpHelpers.DateTimes
{
    class JulianDayHelper
    {
        /// <summary>
        /// 儒略日（Julian day）是指由公元前4713年1月1日，协调世界时中午12时开始所经过的天数，多为天文学家采用，用以作为天文学的单一历法，把不同历法的年表统一起来。
        /// 求出给定年(I)，月(J)，日(K)的儒略日:
        /// 儒略日= K - 32075 + 1461 * (I + 4800 + (J-14)/12)/4+367*(J-2-(J-14)/12*12)/12-3*((I+4900+(J-14)/12)/100)/4
        /// </summary>
        /// <returns></returns>
        public static int GetJulianDay(System.DateTime date)
        {
            int I = date.Year;
            int J = date.Month;
            int K = date.Day;

            return K - 32075 + 1461 * (I + 4800 + (J - 14) / 12) / 4 + 367 * (J - 2 - (J - 14) / 12 * 12) / 12 - 3 * ((I + 4900 + (J - 14) / 12) / 100) / 4;
        }

        /// <summary>
        /// 儒略日（Julian day）是指由公元前4713年1月1日，协调世界时中午12时开始所经过的天数，多为天文学家采用，用以作为天文学的单一历法，把不同历法的年表统一起来。
        /// 求出给定年(I)，月(J)，日(K)的儒略日:
        /// 儒略日= K - 32075 + 1461 * (I + 4800 + (J-14)/12)/4+367*(J-2-(J-14)/12*12)/12-3*((I+4900+(J-14)/12)/100)/4
        /// </summary>
        /// <returns></returns>
        public static int GetJulianNumber(System.DateTime date)
        {
            int I = date.Year;
            int J = date.Month;
            int K = date.Day;

            return K - 32075 + 1461 * (I + 4800 + (J - 14) / 12) / 4 + 367 * (J - 2 - (J - 14) / 12 * 12) / 12 - 3 * ((I + 4900 + (J - 14) / 12) / 100) / 4;
        }

        public static System.DateTime GetJulianDate(double number)
        {
            double JD = number;
            double Z = Math.Floor(JD + 0.5);
            double W = Math.Floor((Z - 1867216.25) / 36524.25);
            double X = Math.Floor(W / 4);
            double AA = Math.Floor(Z + 1 + W - X);
            double BB = Math.Floor(AA + 1524);
            double CC = Math.Floor((BB - 122.1) / 365.25);
            double DD = Math.Floor(365.25 * CC);
            double EE = Math.Floor((BB - DD) / 30.6001);
            double FF = Math.Floor(30.6001 * EE);
            double Day = BB - DD - FF;
            double Month;
            double Year;
            if ((EE - 13) <= 12 && (EE - 13) > 0)
                Month = EE - 13;
            else
                Month = EE - 1;
            if (Month == 1 || Month == 2)
                Year = CC - 4715;
            else
                Year = CC - 4716;


            System.DateTime mytime;
            try
            {
                mytime = new System.DateTime(Convert.ToInt32(Year), Convert.ToInt32(Month), Convert.ToInt32(Day));
            }
            catch (Exception)
            {
                mytime = new System.DateTime(1900, 1, 1);
            }

            return mytime;
        }
    }
}
